﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommonClasses
{
    public class BJGame : Game
    {
        public delegate void WinnerEventHandler(string name, int handTotal);
        public event WinnerEventHandler Winner;
        //public event WinnerEventHandler BJWinner;

        //public delegate void BustedEventHandler(string name, int handTotal);
        //public event BustedEventHandler Busted;

        public delegate void MaxCardReachedEventHandler();
        public event MaxCardReachedEventHandler MaxedCards;

        public delegate void NotEnoughCardsEventHandler();
        public event NotEnoughCardsEventHandler NotEnoughCards;

        BJDeck myBJDeck;
        public BJHand playerHand; 
        public BJHand dealerHand;        

        public override void NewGame()
        {
            myBJDeck = new BJDeck();
            myBJDeck.initialize_cards();                             
        }

        public override void Deal()
        {
            if (myBJDeck.Cards.Count < 10)
            {
                if (NotEnoughCards != null) NotEnoughCards();
                return;
            }

            playerHand = new BJHand();
            dealerHand = new BJHand();

            playerHand.name = "You";
            dealerHand.name = "Dealer"; 

            for (int i = 0; i < 2; i++)
            {
                playerHand.CardsOnHand.Add(myBJDeck.GetCard());
                dealerHand.CardsOnHand.Add(myBJDeck.GetCard());

                switch (i)
                {
                    case 0:
                        playerHand.CardsOnHand[i].FaceDown = false;
                        dealerHand.CardsOnHand[i].FaceDown = false;
                        break;
                    case 1:
                        playerHand.CardsOnHand[i].FaceDown = false;
                        break;
                }
            }
            playerHand.calculate_total();
            dealerHand.calculate_total();

            if (playerHand.Total == 21)
            {
                DealersTurn();
                Evaluate();
            }
        }

        public void DealersTurn()
        {
            // Show Dealer's cards. 
            // Is a must since calculate total method only calculates faced up cards.
            foreach (Card c in dealerHand.CardsOnHand)
            {
                c.FaceDown = false;
            }
                
            dealerHand.calculate_total();            

            // Dealer get card logic.
            while (dealerHand.Total < 17)
            {
                Card face_up_card = myBJDeck.GetCard();

                face_up_card.FaceDown = false;

                dealerHand.CardsOnHand.Add(face_up_card);

                dealerHand.calculate_total();
            }       
        }

        public override void Evaluate()
        {            
            playerHand.calculate_total();
            dealerHand.calculate_total();          

            if ((playerHand.Total < 22) && (dealerHand.Total < 22))
            {
                if (playerHand.Total > dealerHand.Total)
                {                   
                    if (Winner != null) Winner(playerHand.name, playerHand.Total);                                    
                }
                else if (playerHand.Total < dealerHand.Total)
                {                  
                    if (Winner != null) Winner(dealerHand.name, dealerHand.Total);                                          
                }
                else 
                {
                    if (Winner != null) Winner("(Tie) - " + dealerHand.name , dealerHand.Total);                    
                }               
            }
            else if (playerHand.Total > 21)  // If player goes above 21, dealer wins regardless of dealer's hand.
            {
                if (Winner != null) Winner(dealerHand.name, 0);                
            }
            else  // dealer's total count > 21. 
            {
                if (Winner != null) Winner(playerHand.name, 0);   
            }
        }

        public override void PlayerMove()
        {
            if (playerHand.CardsOnHand.Count != playerHand.MaxCards)
            {
                playerHand.CardsOnHand.Add(myBJDeck.GetCard());
                playerHand.CardsOnHand[playerHand.CardsOnHand.Count - 1].FaceDown = false;

                playerHand.calculate_total();

                if (playerHand.Total >= 21)
                {
                    DealersTurn();
                    Evaluate();
                }
            }
            else
            {
                if (MaxedCards != null) MaxedCards();
            }            
        }

        //public ObservableCollection<Card> GetPlayerCardsInPlay()
        //{
        //    ObservableCollection<Card> cardsInPlay = new ObservableCollection<Card>();
        //    foreach (Card c in playerHand.CardsOnHand)
        //    {
        //        if (c.FaceDown == true)
        //        {
        //            c.ImageInUse = c.FDImage;
        //        }
        //        else
        //        {
        //            c.ImageInUse = c.Image;
        //        }
        //        cardsInPlay.Add(c);                
        //    }
        //    return cardsInPlay;
        //}

        //public ObservableCollection<Card> GetDealerCardsInPlay()
        //{
        //    ObservableCollection<Card> cardsInPlay = new ObservableCollection<Card>();
        //    foreach (Card c in dealerHand.CardsOnHand)
        //    {
        //        if (c.FaceDown == true)
        //        {
        //            c.ImageInUse = c.FDImage;
        //        }
        //        else
        //        {
        //            c.ImageInUse = c.Image;
        //        }
        //        cardsInPlay.Add(c);
        //    }
        //    return cardsInPlay;
        //}
    }
}
